<!--
 * @Description: 
 * @Author: xunzhaotech
 * @Email: luyb@xunzhaotech.com
 * @QQ: 1525572900
 * @Date: 2025-03-13 12:21:28
 * @LastEditTime: 2025-03-26 12:51:12
 * @LastEditors: xunzhaotech
-->
<!-- ERP 产品的新增/修改 -->
<template>
  <Dialog :title="dialogTitle" v-model="dialogVisible" width="1200px" height="900px">
    <ContentWrap>
      <!-- 搜索工作栏 -->
      <el-form
        class="-mb-15px"
        :model="queryParams"
        ref="queryFormRef"
        :inline="true"
        label-width="68px"
      >
        <el-form-item label="名称" prop="productName">
          <el-input
            v-model="queryParams.productName"
            placeholder="请输入名称"
            clearable
            @keyup.enter="handleQuery"
            class="!w-240px"
          />
        </el-form-item>
        <el-form-item label="分类" prop="categoryId">
          <el-tree-select
            v-model="queryParams.categoryId"
            :data="categoryList"
            :props="defaultProps"
            check-strictly
            default-expand-all
            placeholder="请选择分类"
            class="!w-240px"
          />
        </el-form-item>
        <el-form-item>
          <el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
          <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
          <el-button type="primary" plain @click="openForm()" v-hasPermi="['erp:product:create']">
            <Icon icon="ep:plus" class="mr-5px" /> 关联零部件
          </el-button>
        </el-form-item>
      </el-form>
    </ContentWrap>
    <ContentWrap>
      <!-- 产品基本信息 -->
      <div class="product-info-card">
        <div class="flex items-center mb-4">
          <div class="info-item mr-6">
            <span class="info-label"><strong>条码：</strong></span>
            <span class="info-value">{{ currentProduct?.barCode || '-' }}</span>
          </div>
          <div class="info-item mr-6">
            <span class="info-label"><strong>名称：</strong></span>
            <span class="info-value">{{ currentProduct?.name || '-' }}</span>
          </div>
          <div class="info-item mr-6">
            <span class="info-label"><strong>分类：</strong></span>
            <span class="info-value">{{ currentProduct?.categoryName || '-' }}</span>
          </div>
          <div class="info-item">
            <span class="info-label"><strong>单位：</strong></span>
            <span class="info-value">{{ currentProduct?.unitName || '-' }}</span>
          </div>
        </div>
      </div>
    </ContentWrap>
    <!-- 列表 -->
    <ContentWrap>
      <el-table
        v-loading="componentsLoading"
        :data="componentsList"
        :stripe="true"
        :show-overflow-tooltip="true"
      >
        <el-table-column label="条码" align="center" prop="barCode" />
        <el-table-column label="名称" align="center" prop="name" />
        <el-table-column label="规格" align="center" prop="standard" />
        <el-table-column label="分类" align="center" prop="categoryName" />
        <el-table-column label="单位" align="center" prop="unitName" />
        <el-table-column label="数量" align="center" prop="quantity">
          <template #default="{ row }">
            <el-input-number
              v-model="row.quantity"
              :min="1"
              :precision="0"
              @change="handleQuantityChange(row)"
              size="small"
              controls-position="right"
            />
          </template>
        </el-table-column>
        <el-table-column label="操作" align="center" width="200">
          <template #default="scope">
            <el-button
              link
              type="danger"
              @click="handleDelete(scope.row.id)"
              v-hasPermi="['erp:product:delete']"
            >
              删除
            </el-button>
          </template>
        </el-table-column>
      </el-table>
      <!-- 分页 -->
      <Pagination
        :total="componentsTotal"
        v-model:page="componentsQuery.pageNo"
        v-model:limit="componentsQuery.pageSize"
        @pagination="loadComponentsList"
      />
    </ContentWrap>
    <template #footer>
      <el-button @click="submitForm" type="primary" :disabled="formLoading">保存</el-button>
      <el-button @click="dialogVisible = false">取 消</el-button>
    </template>
  </Dialog>
  <!-- 零部件关联表单组件 -->
  <ComponentsRelationForm ref="componentsRelationFormRef" @result="result" />
</template>
<script setup lang="ts">
import { ProductApi, ProductVO } from '@/api/erp/product/product'
import { ProductCategoryApi, ProductCategoryVO } from '@/api/erp/product/category'
import { ProductUnitApi, ProductUnitVO } from '@/api/erp/product/unit'
import { ProductComponentsVO } from '@/api/erp/product/productcomponents'
import { handleTree } from '@/utils/tree'
import ComponentsRelationForm from './ComponentsRelationForm.vue'

/** ERP 产品 表单 */
defineOptions({ name: 'ComponentsForm' })

const message = useMessage() // 消息弹窗

const dialogVisible = ref(false) // 弹窗的是否展示
const dialogTitle = ref('') // 弹窗的标题
const formLoading = ref(false) // 表单的加载中：1）修改时的数据加载；2）提交的按钮禁用
const queryFormRef = ref() // 查询表单 Ref
const formRef = ref() // 表单 Ref
const categoryList = ref<ProductCategoryVO[]>([]) // 产品分类列表
const unitList = ref<ProductUnitVO[]>([]) // 产品单位列表
const componentsList = ref<ProductComponentsVO[]>([]) // 产品零部件列表
const componentsLoading = ref(false) // 零部件列表加载状态
const componentsTotal = ref(0) // 零部件列表总数
const currentProduct = ref<ProductVO | null>(null) // 当前产品对象，保存父页面传递的完整产品信息
const componentsQuery = ref({
  pageNo: 1,
  pageSize: 10,
  id: undefined as number | undefined
}) // 零部件查询参数
const queryParams = ref({
  productName: '',
  categoryId: undefined,
  pageNo: 1,
  pageSize: 10
}) // 搜索参数
const defaultProps = {
  children: 'children',
  label: 'name',
  value: 'id'
} // 树形选择器配置

/** 打开弹窗 */
const open = async (row: ProductVO) => {
  dialogVisible.value = true
  dialogTitle.value = '零部件管理'
  resetForm()
  // 保存完整的产品对象
  if (row) {
    formLoading.value = true
    try {
      // 直接使用传入的产品对象，不再从API获取
      currentProduct.value = row
      // 加载产品零部件列表
      componentsQuery.value.id = row.id
      await loadComponentsList(row.id)
    } finally {
      formLoading.value = false
    }
  }
  // 产品分类
  const categoryData = await ProductCategoryApi.getProductCategorySimpleList({ type: 'components' })
  categoryList.value = handleTree(categoryData, 'id', 'parentId')
  // 产品单位
  unitList.value = await ProductUnitApi.getProductUnitSimpleList({ type: 'components' })
}

/** 加载产品零部件列表 */
const loadComponentsList = async (id?: number) => {
  componentsLoading.value = true
  try {
    // 如果传入了productId，更新查询参数
    if (id !== undefined) {
      componentsQuery.value.id = id
    }
    // 确保有productId才进行查询
    if (componentsQuery.value.id) {
      const res = await ProductApi.getComponentsPage({
        ...queryParams.value,
        id: componentsQuery.value.id
      })
      componentsList.value = res.list || []
      componentsTotal.value = res.total || 0
    }
  } catch (error) {
    message.error('加载零部件列表失败')
  } finally {
    componentsLoading.value = false
  }
}
const result = async (selectedComponents: ProductComponentsVO[]) => {
  if (!currentProduct.value || !selectedComponents.length) return

  // 检查是否有选中的产品
  if (selectedComponents.length === 0) {
    message.warning('请至少选择一个零部件')
    return
  }

  // 过滤掉已经存在的零部件，防止重复添加
  const newComponents = selectedComponents.filter((component) => {
    // 检查是否已存在相同id的零部件
    return !componentsList.value.some((existingComponent) => existingComponent.id === component.id)
  })

  // 如果所有选中的零部件都已存在，提示用户
  if (newComponents.length === 0) {
    message.warning('所选零部件已全部关联，请选择其他零部件')
    return
  }

  // 只添加新的零部件
  componentsList.value = [...componentsList.value, ...newComponents]
  message.success(`成功关联${newComponents.length}个零部件`)
}
defineExpose({ open }) // 提供 open 方法，用于打开弹窗

/** 提交表单 */
const emit = defineEmits(['success']) // 定义 success 事件，用于操作成功后的回调
const submitForm = async () => {
  if (!currentProduct.value || !currentProduct.value.id) {
    message.warning('产品信息不完整，无法提交')
    return
  }

  if (componentsList.value.length === 0) {
    message.warning('请至少添加一个零部件')
    return
  }

  formLoading.value = true
  try {
    // 构建请求数据并去重
    // 使用Map来确保相同componentId的零部件只会被提交一次，保留最新的quantity值
    const componentsMap = new Map()
    componentsList.value.forEach((item) => {
      componentsMap.set(item.id, {
        productId: currentProduct.value?.id,
        componentId: item.id,
        quantity: item.quantity
      })
    })

    // 将Map转换为数组
    const data = Array.from(componentsMap.values())

    // 调用API保存零部件关联
    await ProductApi.saveProductComponents(data)
    message.success('保存成功')
    dialogVisible.value = false
    emit('success') // 通知父组件刷新数据
  } catch (error) {
    message.error('保存失败')
  } finally {
    formLoading.value = false
  }
}
/** 重置表单 */
const resetForm = () => {
  formRef.value?.resetFields()
}

/** 搜索按钮操作 */
const handleQuery = async () => {
  componentsQuery.value.pageNo = 1
  await loadComponentsList()
}

/** 重置按钮操作 */
const resetQuery = () => {
  queryFormRef.value?.resetFields()
  handleQuery()
}

/** 打开零部件关联表单 */
const componentsRelationFormRef = ref()
const openForm = async () => {
  // 检查是否有当前产品信息
  if (!currentProduct.value) {
    message.warning('请先选择产品')
    return
  }
  // 调用零部件关联表单的open方法，传入当前产品和已添加的零部件列表
  componentsRelationFormRef.value.open(currentProduct.value, componentsList.value)
}

/** 处理数量变更 */
const handleQuantityChange = async (row: ProductComponentsVO) => {
  try {
    console.log('更新零部件数量', row.id, row.quantity)
  } catch (error) {
    message.error('更新零部件数量失败')
  }
}

/** 删除零部件 */
const handleDelete = (id: number) => {
  // 从列表中过滤掉要删除的零部件
  componentsList.value = componentsList.value.filter((item) => item.id !== id)
  message.success('删除成功')
}
</script>
